package com.example.backend.service;

import com.example.backend.dto.WebSocketMessageDto;
import com.example.backend.domain.enums.WebSocketMessageType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * WebSocket服务类
 * 提供消息广播和定向推送功能
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class WebSocketService {

    private final SimpMessagingTemplate messagingTemplate;
    
    // 存储在线用户
    private final ConcurrentMap<String, String> onlineUsers = new ConcurrentHashMap<>();

    /**
     * 广播消息给所有在线用户
     */
    public void broadcastMessage(WebSocketMessageDto message) {
        try {
            // 设置消息ID和时间戳
            if (message.getMessageId() == null) {
                message.setMessageId(UUID.randomUUID().toString());
            }
            if (message.getTimestamp() == null) {
                message.setTimestamp(LocalDateTime.now());
            }

            // 发送到topic频道
            messagingTemplate.convertAndSend("/topic/broadcast", message);
            
            log.info("广播消息成功: type={}, title={}, onlineUsers={}", 
                    message.getType(), message.getTitle(), onlineUsers.size());
        } catch (Exception e) {
            log.error("广播消息失败", e);
        }
    }

    /**
     * 发送消息给指定用户
     */
    public void sendToUser(String username, WebSocketMessageDto message) {
        try {
            // 设置消息ID和时间戳
            if (message.getMessageId() == null) {
                message.setMessageId(UUID.randomUUID().toString());
            }
            if (message.getTimestamp() == null) {
                message.setTimestamp(LocalDateTime.now());
            }

            // 发送到用户专用队列
            messagingTemplate.convertAndSendToUser(username, "/queue/messages", message);
            
            log.info("发送消息给用户成功: username={}, type={}, title={}", 
                    username, message.getType(), message.getTitle());
        } catch (Exception e) {
            log.error("发送消息给用户失败: username={}", username, e);
        }
    }

    /**
     * 发送消息给多个用户
     */
    public void sendToUsers(List<String> usernames, WebSocketMessageDto message) {
        usernames.forEach(username -> sendToUser(username, message));
    }

    /**
     * 发送工单分配通知
     */
    public void sendTicketAssignedNotification(String assigneeUsername, Long ticketId, String ticketTitle, String assignerName) {
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.TICKET_ASSIGNED)
                .title("工单分配通知")
                .content(String.format("您收到了新的工单：%s", ticketTitle))
                .sender(WebSocketMessageDto.SenderInfo.builder()
                        .displayName(assignerName)
                        .role("系统")
                        .build())
                .entity(WebSocketMessageDto.EntityInfo.builder()
                        .entityType("ticket")
                        .entityId(ticketId)
                        .entityTitle(ticketTitle)
                        .entityUrl("/tickets/" + ticketId)
                        .build())
                .priority(4)
                .requiresAck(true)
                .build();

        sendToUser(assigneeUsername, message);
    }

    /**
     * 发送工单状态变更通知
     */
    public void sendTicketStatusChangedNotification(String username, Long ticketId, String ticketTitle, 
                                                   String oldStatus, String newStatus) {
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.TICKET_STATUS_CHANGED)
                .title("工单状态变更")
                .content(String.format("工单 %s 状态从 %s 变更为 %s", ticketTitle, oldStatus, newStatus))
                .entity(WebSocketMessageDto.EntityInfo.builder()
                        .entityType("ticket")
                        .entityId(ticketId)
                        .entityTitle(ticketTitle)
                        .entityUrl("/tickets/" + ticketId)
                        .build())
                .priority(3)
                .requiresAck(false)
                .build();

        sendToUser(username, message);
    }

    /**
     * 发送新评论通知
     */
    public void sendNewCommentNotification(String username, Long ticketId, String ticketTitle, 
                                         String commenterName, String commentContent) {
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.COMMENT_ADDED)
                .title("新评论通知")
                .content(String.format("%s 在工单 %s 中添加了新评论", commenterName, ticketTitle))
                .sender(WebSocketMessageDto.SenderInfo.builder()
                        .displayName(commenterName)
                        .role("用户")
                        .build())
                .entity(WebSocketMessageDto.EntityInfo.builder()
                        .entityType("comment")
                        .entityId(ticketId)
                        .entityTitle(ticketTitle)
                        .entityUrl("/tickets/" + ticketId)
                        .build())
                .priority(3)
                .requiresAck(false)
                .build();

        sendToUser(username, message);
    }

    /**
     * 发送系统通知
     */
    public void sendSystemNotification(String title, String content, Integer priority) {
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.SYSTEM_NOTIFICATION)
                .title(title)
                .content(content)
                .sender(WebSocketMessageDto.SenderInfo.builder()
                        .displayName("系统管理员")
                        .role("系统")
                        .build())
                .priority(priority != null ? priority : 2)
                .requiresAck(false)
                .build();

        broadcastMessage(message);
    }

    /**
     * 用户上线通知
     */
    public void notifyUserOnline(String username) {
        onlineUsers.put(username, LocalDateTime.now().toString());
        
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.USER_ONLINE)
                .title("用户上线")
                .content(String.format("用户 %s 已上线", username))
                .priority(1)
                .requiresAck(false)
                .build();

        broadcastMessage(message);
    }

    /**
     * 用户下线通知
     */
    public void notifyUserOffline(String username) {
        onlineUsers.remove(username);
        
        WebSocketMessageDto message = WebSocketMessageDto.builder()
                .type(WebSocketMessageType.USER_OFFLINE)
                .title("用户下线")
                .content(String.format("用户 %s 已下线", username))
                .priority(1)
                .requiresAck(false)
                .build();

        broadcastMessage(message);
    }

    /**
     * 获取在线用户数量
     */
    public int getOnlineUserCount() {
        return onlineUsers.size();
    }

    /**
     * 获取在线用户列表
     */
    public ConcurrentMap<String, String> getOnlineUsers() {
        return new ConcurrentHashMap<>(onlineUsers);
    }

    /**
     * 检查用户是否在线
     */
    public boolean isUserOnline(String username) {
        return onlineUsers.containsKey(username);
    }
}
